package com.zmkj.cn.comm.aop;


import com.alibaba.fastjson.JSON;
import com.zmkj.cn.comm.exception.BaseException;
import com.zmkj.cn.comm.listener.InitDataListener;
import com.zmkj.cn.comm.vo.RestVo;
import com.zmkj.cn.sys.dto.SysManagerDto;
import com.zmkj.cn.sys.service.ISysLogService;
import com.zmkj.cn.comm.util.IpUtils;
import com.zmkj.cn.comm.util.ThreadLocalUtil;
import com.zmkj.cn.comm.vo.CommonResultVo;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;


/**
 * 处理公共返回的对象
 */
@Aspect
@Component
@Slf4j
@Order(2)
public class WebAop {


    @Autowired
    private ISysLogService sysLogService;

    /**
     * 设置切入点未restTemplete下的所有方法
     */
    @Pointcut("execution(public * com.zmkj.cn.*.controller..*.*(..))")
    public void aopController() {
    }




    @Around("aopController()")
    public Object arround(ProceedingJoinPoint pjp) {
        //获取目标方法体参数
        Object[] parames = pjp.getArgs();
        //返回公共信息
        Object object= createCommonResponse(pjp, parames);
        return object;
    }


    private Object createCommonResponse(ProceedingJoinPoint pjp, Object[] parames) {
        //获取request
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();
        //记录请求路径url
        log.info("请求url={},请求方法method={},请求IP地址ip={},传递参数args={}",
                request.getRequestURL(), request.getMethod(), request.getRemoteAddr(), JSON.toJSON(request.getParameterMap()).toString());
        CommonResultVo responseVo = new CommonResultVo();
        responseVo.setEdition(InitDataListener.editions);
        Long startTime = System.currentTimeMillis();
        String ip=IpUtils.getIpAddress(request);
        String url=request.getRequestURL().toString();
        String code=null;
        try {
            Object o = pjp.proceed(parames);
            if(o instanceof RestVo){
                return ((RestVo) o).getValue();
            }

            if(o instanceof ModelAndView || o instanceof CommonResultVo){
                return o;
            }
            createResponseInfo(responseVo, o, 0, "操作成功");
            code="0";
            return responseVo;
        } catch (Throwable e) {
            log.error(e.getMessage(),e);

            if (e instanceof BaseException) {
                code=((BaseException) e).getCode()+"";
                createResponseInfo(responseVo, null, ((BaseException) e).getCode(), ((BaseException) e).getMsg());
            } else {
                code="-1";
                createResponseInfo(responseVo, null, -1, "操作失败");
            }
            return responseVo;
        } finally {
            Long endTime = System.currentTimeMillis();
            Long reqTimes = endTime - startTime;
            int respState = 0;
            if (responseVo.getCode() == 0) {
                respState = 1;
            }
            log.info("返回参数：" + JSON.toJSONString(responseVo).toString() + "，响应时间毫秒：" + reqTimes);
            SysManagerDto sysManagerDto= ThreadLocalUtil.getCurrentManagerWithNoCheck();
            Integer reqId=null;
            if(sysManagerDto!=null){
                reqId=sysManagerDto.getId();
            }
            sysLogService.saveLog(ip,url,respState+"",reqTimes,JSON.toJSONString(request.getParameterMap()),reqId+"");
        }
    }





    private void createResponseInfo(CommonResultVo responseVo, Object body, int code, String msg) {
        responseVo.setBody(body);
        responseVo.setCode(code);
        responseVo.setMsg(msg);
    }
}
